package com.huaxin.device.dto.enums.schemes;

import java.util.Arrays;
import java.util.Optional;

/**
 * 数据库表字段名校验工具类
 * 基于 DatabaseSchema 枚举实现字段名合法性校验
 * 支持忽略大小写匹配
 */
public class SchemaValidator {

    /**
     * 判断指定表中是否包含该字段名（忽略大小写）
     *
     * @param table     表枚举
     * @param fieldName 字段名
     * @return true 如果字段名合法，false 否则
     */
    public static boolean isValidField(DatabaseSchema table, String fieldName) {
        if (table == null || fieldName == null || fieldName.trim().isEmpty()) {
            return false;
        }
        String trimmed = fieldName.trim();
        return Arrays.stream(table.getFields())
                .anyMatch(f -> f.getFieldName().equalsIgnoreCase(trimmed));
    }

    /**
     * 根据字段名获取字段枚举（区分表）
     *
     * @param table     表枚举
     * @param fieldName 字段名
     * @return Optional<Field>，存在则返回，否则 empty
     */
    public static Optional<DatabaseSchema.Field> getFieldByName(DatabaseSchema table, String fieldName) {
        if (table == null || fieldName == null || fieldName.trim().isEmpty()) {
            return Optional.empty();
        }
        String trimmed = fieldName.trim();
        return Arrays.stream(table.getFields())
                .filter(f -> f.getFieldName().equalsIgnoreCase(trimmed))
                .findFirst();
    }

    /**
     * 根据表名字符串（如 "device_readings_circuit_breaker"）获取 DatabaseSchema 枚举
     *
     * @param tableName 表名（数据库表名，不区分大小写）
     * @return Optional<DatabaseSchema>，存在则返回，否则 empty
     */
    public static Optional<DatabaseSchema> getTableByTableName(String tableName) {
        if (tableName == null || tableName.trim().isEmpty()) {
            return Optional.empty();
        }
        String trimmed = tableName.trim();
        return Arrays.stream(DatabaseSchema.values())
                .filter(t -> t.getTableName().equalsIgnoreCase(trimmed))
                .findFirst();
    }

    /**
     * 校验表名和字段名是否都合法
     *
     * @param tableName 表名字符串
     * @param fieldName 字段名
     * @return ValidationResult 校验结果
     */
    public static ValidationResult validateTableAndField(String tableName, String fieldName) {
        Optional<DatabaseSchema> tableOpt = getTableByTableName(tableName);
        if (tableOpt.isEmpty()) {
            return new ValidationResult(false, "表名不合法: " + tableName);
        }

        if (!isValidField(tableOpt.get(), fieldName)) {
            return new ValidationResult(false, "字段 '" + fieldName + "' 不属于表 '" + tableName + "'");
        }

        return new ValidationResult(true, "校验通过");
    }

    /**
     * 批量校验多个字段名是否都属于指定表
     *
     * @param table      表枚举
     * @param fieldNames 字段名列表
     * @return ValidationResult，包含非法字段列表
     */
    public static ValidationResult validateFields(DatabaseSchema table, String... fieldNames) {
        if (fieldNames == null || fieldNames.length == 0) {
            return new ValidationResult(true, "无字段需要校验");
        }

        final String[] invalidFields = Arrays.stream(fieldNames)
                .filter(fieldName -> !isValidField(table, fieldName))
                .toArray(String[]::new);

        if (invalidFields.length > 0) {
            return new ValidationResult(false, "非法字段: " + String.join(", ", invalidFields));
        }

        return new ValidationResult(true, "所有字段均合法");
    }

    // ==================== 内部类：校验结果 ====================

    /**
     * 校验结果封装类
     */
    public static class ValidationResult {
        private final boolean valid;
        private final String message;

        public ValidationResult(boolean valid, String message) {
            this.valid = valid;
            this.message = message;
        }

        public boolean isValid() {
            return valid;
        }

        public String getMessage() {
            return message;
        }

        /**
         * 快速抛出异常（如果不合法）
         */
        public void orThrow() {
            if (!valid) {
                throw new IllegalArgumentException(message);
            }
        }
    }
}